import imageCompression from 'browser-image-compression'
/**
 * 将文件大小转换为带单位的大小
 * @param size 文件大小（以字节为单位）
 * @returns 格式化后的文件大小字符串
 */
function formatFileSize(size: number): string {
  if (size < 1024) {
    return `${size} B`
  } else if (size < 1024 * 1024) {
    return `${(size / 1024).toFixed(2)} KB`
  } else if (size < 1024 * 1024 * 1024) {
    return `${(size / (1024 * 1024)).toFixed(2)} MB`
  } else {
    return `${(size / (1024 * 1024 * 1024)).toFixed(2)} GB`
  }
}

/**
 * 生成压缩记录
 * @param file 原始文件
 * @param blob 压缩后的 Blob 对象
 * @param compressStartTime 压缩开始时间戳
 */
function generateCompressRecord(file: File, blob: Blob, compressStartTime: number) {
  const compressEndTime = Date.now()
  const originalSize = file.size
  const compressedSize = blob.size
  const compressionTime = (compressEndTime - compressStartTime) / 1000
  const compressionRatio = originalSize === 0 ? 'N/A' : `${(((originalSize - compressedSize) / originalSize) * 100).toFixed(2)}%`

  const compressRecord = {
    名称: file.name,
    初始大小: formatFileSize(originalSize),
    压缩后大小: formatFileSize(compressedSize),
    压缩时长: `${compressionTime}s`,
    压缩率: compressionRatio,
  }

  // 控制台打印
  console.table(compressRecord)
}

/**
 * 图片压缩
 * @param {*} option 配置项
 * @returns null
 */
export default function MyCompress(option: {
  fileItem: any
  onProgress?: (progress: number) => void
  success?: (compressedFile: File) => void
}): void {
  // 压缩逻辑
  const options = {
    maxSizeMB: 5, // 最大文件大小（MB）
    maxWidthOrHeight: 1920, // 最大宽度或高度（像素）
    initialQuality: 1, // 图片质量（0-1）
    useWebWorker: false, // 使用 Web Worker 进行非阻塞压缩，不建议开启，开启后会从 https://cdn.jsdelivr.net 拉取 worker 脚本，有时这个网站加载比较慢
    preserveExif: true, // 保留 EXIF 信息
    onProgress: (progress: number) => {
      // 将 progress 改为 0-1
      const percent = progress / 100
      option.fileItem.percent = percent
      if (option.onProgress) {
        option.onProgress(percent)
      }
    },
  }
  const file = option.fileItem.file

  // 压缩开始时间戳
  const compressStartTime = Date.now()
  // 压缩图片
  imageCompression(file, options)
    .then((blob) => {
      // 压缩后的图片
      const compressedFile = new File([blob], option.fileItem.name, {
        type: blob.type,
        lastModified: Date.now(),
      })
      if (option.success) {
        option.success(compressedFile)
      }
      // 压缩记录 begin
      generateCompressRecord(file, blob, compressStartTime)
      // 压缩记录 end
    })
    .catch((error) => {
      console.error('压缩失败:', error)
      console.log('回退到采用原文件上传')
      if (option.success) {
        option.success(file)
      }
    })
}
